package com.cloudcross.ssp.base.dao;

import java.util.List;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.cloudcross.ssp.listener.InitData;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

/**
 * 接口的实现
 * 
 * @author 杜武強
 */
public class MongoDBDaoImpl implements MongoDBDao {

    //MongoClient的实例代表数据库连接池，是线程安全的，可以被多线程共享，客户端在多线程条件下仅维持一个实例即可
    private MongoClient           mongoClient    = null;

    private String                host           = (String) InitData.getMongoDBInfo("host");
    private int                   port           = Integer.parseInt(InitData.getMongoDBInfo("port").toString());
    private String                user           = (String) InitData.getMongoDBInfo("user");
    private String                pwd            = (String) InitData.getMongoDBInfo("pass");

    //使用单例模式保证线程安全
    private static MongoDBDaoImpl mongoDBDaoImpl = new MongoDBDaoImpl();

    private MongoDBDaoImpl() {
        return;
    }

    public static MongoDBDaoImpl getMongoDBDaoImplInstance() {
        return mongoDBDaoImpl;
    }

    @Override
    public void insertOne(String dbName, String dbCollection, Document document) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection).insertOne(document);
    }

    @Override
    public void insertMany(String dbName, String dbCollection, List<Document> documents) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection).insertMany(documents);
    }

    @Override
    public void updateOne(String dbName, String dbCollection, Bson filterDocument, Document newDocument) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection)
                .updateOne(filterDocument, new Document("$set", newDocument));
    }

    @Override
    public void replaceOne(String dbName, String dbCollection, Bson filterDocument, Document newDocument) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection).replaceOne(filterDocument, newDocument);
    }

    @Override
    public void delete(String dbName, String dbCollection, Bson filterDocument) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection).deleteMany(filterDocument);
    }

    @Override
    public FindIterable<Document> find(String dbName, String dbCollection, Bson filterDocument) {
        if (null == filterDocument) {
            return mongoClient.getDatabase(dbName).getCollection(dbCollection).find();
        }

        return mongoClient.getDatabase(dbName).getCollection(dbCollection).find(filterDocument);
    }

    @Override
    public long count(String dbName, String dbCollection) {
        return mongoClient.getDatabase(dbName).getCollection(dbCollection).count();
    }

    @Override
    public long count(String dbName, String dbCollection, Bson filter) {
        return mongoClient.getDatabase(dbName).getCollection(dbCollection).count(filter);
    }

    @Override
    public void updateMany(String dbName, String dbCollection, Bson filterDocument, Document newDocument) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection)
                .updateMany(filterDocument, new Document("$set", newDocument));
    }

    @Override
    public MongoDatabase getDataBase(String dbName) {
        return mongoClient.getDatabase(dbName);
    }

    @Override
    public MongoCollection<Document> getCollection(String dbName, String dbCollection) {
        return mongoClient.getDatabase(dbName).getCollection(dbCollection);
    }

    @Override
    public void creatIndex(String dbName, String dbCollection, Bson keys) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection).createIndex(keys);
    }

    @Override
    public void dropIndex(String dbName, String dbCollection, String index) {
        mongoClient.getDatabase(dbName).getCollection(dbCollection).dropIndex(index);
    }

    @Override
    public Document findOne(String dbName, String dbCollection, Bson filterDocument) {
        FindIterable<Document> iterator = mongoClient.getDatabase(dbName).getCollection(dbCollection)
                .find(filterDocument);
        return iterator.first();
    }

}
